#pragma once

#include <cstdlib>
#include <SDL.h>
#include <SDL_image.h>
#include <fstream>
#include <iostream>
#include <map>
#include <list>

#include "Inventory/Item.h"

using namespace std;

class Anim
{
public:
    int x,y,w,h,quantity;
    float speed,frame;
    SDL_Surface *gfx;
    SDL_Rect srcrect;

    Anim(const char* name, int posx, int posy, int width, int height, int q, int r, int g, int b, float speed);
    Anim(Anim *templ);
    void setRect(int direction);
    void setRectSta(int nr);
};

class Gfx
{
public:
    int which,quantity;
    Anim **anim;

    Gfx(int q);
    Gfx(Gfx *gfx);


    void blitAni(SDL_Surface *screen, int x, int y, int direction);

    void blitSta(SDL_Surface *screen, int x, int y, int type, int nr);
};

class World;
class Character
{
public:
    Character *next;
    int life;
    int maxLife;
    int armor;
    int strenght;
    int exp;
    int level;
    int maxLevel;
    bool dead;
    bool dying;
    bool frozen;
    bool atacking;
    float speed;
    float x,y;
    float vx,vy;
    float destx, desty;
    int direction;
    Gfx *gfx;
    SDL_Surface *screen;

    //odnośne do playera
	list<Weapon> weapons;
	list<Armor> armors;
	list<Weapon>::iterator activeWeapon;
	list<Armor>::iterator activeArmor;
	unsigned smallPotionsNumber;
	unsigned bigPotionsNumber;

    Character(int posx, int posy, float sp, int maxLife);

    void go(float posx, float posy);

    void put(float posx, float posy);
    void putAll(Character *charlist, float layery, float posx, float posy);

    void addGfx(int q);
    void addGfx(Gfx *g);
    void addAnim(const char* name, int posx, int posy, int width, int height, int q, int r, int g, int b, float speed, int which);

    bool attack(World *world, Character *charlist, int x, int y);
    void hurt(int power);
    void die();

    int* getExpLevels () {
		static int expLevels[] = {0, 100, 200, 400, 800, 1600, 3200, 6400};
		return expLevels;
    }

    void addExp(int q) {
		exp += q;
		if (exp > getExpLevels()[maxLevel]) exp = getExpLevels()[maxLevel];
		if (exp > getExpLevels()[level])
			level++;
	    printf("level: %d %d %d\n", level, exp, getExpLevels()[level]);
    }

    float getSpeed() {
		return speed * (1 + level/(float)maxLevel);
    }

    int getMaxLife() {
		return maxLife * (1 + level/(float)maxLevel);
    }

    int getStrenght() {
		return strenght * (1 + level/(float)maxLevel);
    }

    void useSmallPotion() {
	    if (smallPotionsNumber && getMaxLife() != life) {
			life += 30;
			if (life > getMaxLife())
				life = getMaxLife();
			--smallPotionsNumber;
	    }
    }

    void useBigPotion() {
	    if (bigPotionsNumber && getMaxLife() != life) {
		    life += 60;
		    if (life > getMaxLife())
				life = getMaxLife();
		    --bigPotionsNumber;
	    }
    }
};

class Tile
{
public:
    int ground;
    int build;
    int imgNr;
};


class Map
{
public:
    int w, h;
    int seex, seey;
    Gfx *terrain;
    Tile **tile;
    SDL_Surface *screen;
    Character *player;

    Map(int seex, int seey, const char* name, Character *p, Gfx *gfx);
    void reload(int seex, int seey, const char* name);
    void blit(int x, int y, int layer, int shiftx, int shifty);
    void addGfx(int q);
    void addAnim(const char* name, int posx, int posy, int width, int height, int q, int r, int g, int b, float speed, int which);
    void convTerrain(const char* name);
};

class World
{
public:
    Character *player;
    Character *chartemplates;
    Character *charlist;
    Gfx **gfx;
    SDL_Surface *screen, *screenmain;
    Map *map;
    //int sx,sy;
    SDL_Rect *maindstrect;


    World(const char* config, SDL_Surface* screenmain, int, int);
    void addCharacter(float x, float y, float speed, int maxLife, int which);
    void mouseClick(int x, int y, int button);
    void run();
    void draw();
};
